﻿/**************************************************************************
    Sayfa:  ReportViewControl için referans yönlendirici olarak, veritabanındaki tüm raporların listesini içerisi ve her bir treeview.node ile istenen rapora yönlendirmeye yarar.

    Tarih           Sürüm       Değişiklik          İşlem
    --------------------------------------------------------------------------
    2013.Kas        1           Mehmet A. ORAKCI  Oluşturuldu.

****************************************** mehmetakiforakci@gmail.com ****/

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Web.Script.Serialization;
using System.Web.UI;

namespace RaporProj
{
    /// <summary>
    /// Add, Edit, Delete işlemlerinde client side'a callback ile döndürülen json data classıdır.
    /// </summary>
    public class EditorProcess
    {
        public ProcessModes Mode { get; set; }
        public Boolean IsOkay { get; set; }
        public String Message { get; set; }
        public Int32 EntityId { get; set; }
        public String Name { get; set; }
        public Int32 CategoryId { get; set; }
        public Boolean FileChanged { get; set; }
        public String FileName { get; set; }
        public Byte[] FileData { get; set; }
        public String Exception { get; set; }
    }

    public partial class ReportsTreeControl : System.Web.UI.UserControl
    {
        /// <summary>
        /// Rapor TreeView kontrolü üzerinde sağ tıklatarak yapılan işlemleri kapatmak için kullanılır. 
        /// Mark-up tarafından false edilirse, client side'ta popup context menü açılmaz
        /// </summary>
        [DefaultValue(true)]
        public Boolean EnableEditor { get; set; }

        protected override void OnLoad(EventArgs e)
        {
            Page.ClientScript.RegisterClientScriptBlock(typeof(string), "Report.EnableEditor", String.Format(@"
                <script type='text/javascript'>
                    Report.EnableEditor = {0};
                </script>", EnableEditor ? "true" : "false"));

            base.OnLoad(e);

            if (!IsPostBack)
            {
                IReportProvider provider = DataProviderFactory.CreateReportProvider();
                IEnumerable<IReport> reports = provider.GetReports();
                ReportsTreeView.Nodes.Clear();

                foreach (var cat in reports.Where(c => c.IsGroup))
                {
                    this.ReportsTreeView.Nodes.Add(cat.Name, cat.Id.ToString(), "../ReportImages/folder.png");

                    foreach (var rep in reports.Where(r => r.ParentId == cat.Id))
                    {
                        this.ReportsTreeView.Nodes.Find(n => n.Name == cat.Id.ToString())
                            .Nodes.Add(rep.Name, rep.Id.ToString(), "../ReportImages/document.png");
                    }
                }

                this.ReportsTreeView.ExpandAll();
            }
        }

        protected void ReportEditorCallback_Callback(object source, DevExpress.Web.ASPxCallback.CallbackEventArgs e)
        {
            EditorProcess obj = new EditorProcess();
            JavaScriptSerializer ser = new JavaScriptSerializer();

            if (string.IsNullOrEmpty(e.Parameter))
            {
                obj.IsOkay = false;
                obj.Message = "Beklenen parametreler yok, işleme devam edilemiyor.";
            }
            else
            {
                #region Get > Is Process Ok ?
                try
                {
                    Dictionary<string, object> process = ser.Deserialize<Dictionary<string, object>>(e.Parameter);
                    obj.Mode = (ProcessModes)Convert.ToInt32(process["Mode"]); // Geleni geri gönder
                    obj.EntityId = Convert.ToInt32(process["EntityId"]);
                    obj.Name = process["Name"] == null ? null : process["Name"].ToString();
                    obj.CategoryId = Convert.ToInt32(process["CategoryId"]);
                    obj.FileChanged = Convert.ToBoolean(process["FileChanged"]);
                    obj.FileName = process["FileName"] == null ? null : process["FileName"].ToString();
                    obj.IsOkay = true; // parametre okuma işlemi ok
                }
                catch (Exception ex)
                {
                    obj.IsOkay = false;
                    obj.Message = "Parametreler okunamadı, işleme devam edilemiyor. \r\nHata: " + ex.Message;
                    obj.Exception = ex.Source + Environment.NewLine + ex.StackTrace;
                }
                #endregion

                if (obj.IsOkay)
                {
                    obj.IsOkay = false;
                    IReportProvider provider = DataProviderFactory.CreateReportProvider();
                    try
                    {
                        switch (obj.Mode)
                        {
                            #region No Process
                            case ProcessModes.None:
                                obj.IsOkay = false;
                                obj.Message = "İşlem tipi belirsiz.";
                                break;
                            #endregion

                            #region Report processes

                            case ProcessModes.AddReport: // Rapor categori kaydını alır, ReportId aslında kategorinin ID'sidir.
                                obj.IsOkay = true;
                                break;
                            case ProcessModes.EditReport: // Rapor kaydını gönder, hangi rapor değişecek, hangi kategoride ?
                                {
                                    IReport eRep = provider.GetReport(obj.EntityId, false);
                                    obj.IsOkay = eRep != null;
                                    obj.Name = eRep.Name;
                                    obj.FileName = eRep.FileName;
                                    obj.CategoryId = eRep.ParentId;
                                } break;
                            case ProcessModes.DeleteReport: // Gösterilecek mesajı ve silinecek raporu gönder
                                {
                                    IReport dRep = provider.GetReport(obj.EntityId, false);
                                    obj.IsOkay = dRep != null;
                                    obj.Message = obj.IsOkay
                                        ? String.Format("'{0}' kategorisindeki '{1}' adlı raporu silmek istediğinizden emin misiniz?", dRep.CategoryName, dRep.Name)
                                        : "İşlem tamamlanamadı !";
                                } break;
                            #endregion

                            #region Category processes

                            case ProcessModes.AddCategory:
                                obj.IsOkay = true;
                                break;
                            case ProcessModes.EditCategory:
                                {
                                    ICategory eCat = provider.GetCategory(obj.EntityId);
                                    obj.IsOkay = eCat != null;
                                    obj.Name = eCat.CategoryName;
                                    obj.CategoryId = eCat.Id;
                                } break;
                            case ProcessModes.DeleteCategory:
                                {
                                    ICategory dCat = provider.GetCategory(obj.EntityId);
                                    obj.IsOkay = dCat != null;
                                    obj.Name = dCat.CategoryName;
                                    obj.CategoryId = dCat.Id;
                                    obj.Message = obj.IsOkay
                                        ? String.Format("'{0}' adlı rapor kategorisini silmek istediğinizden emin misiniz?", dCat.CategoryName)
                                        : "İşlem tamamlanamadı !";
                                }
                                break;
                            #endregion

                            #region Report results

                            case ProcessModes.AddReportResult:
                                {
                                    // Dosya verilmemişse işleme izin vermez. (Client'ta da seçime izin vermez zaten)
                                    if (String.IsNullOrEmpty(obj.FileName))
                                        throw new Exception("Yeni rapor ekleyebilmek için .repx formatında bir dosya seçiniz.");
                                    string file = MapPath("~/ReportFiles/" + obj.FileName);
                                    obj.FileData = File.ReadAllBytes(file);
                                    obj.IsOkay = provider.AddReport(obj.Name, obj.CategoryId, obj.FileName, obj.FileData);
                                    obj.FileName = Path.GetFileName(file);
                                    File.Delete(file);
                                    obj.Message = obj.IsOkay ? "İşlem başarılı." : "İşlem tamamlanamadı !";
                                }
                                break;
                            case ProcessModes.EditReportResult:
                                {
                                    // Dosya değişmemişse sadece diğer bilgileri update eder.
                                    if (obj.FileChanged)
                                    {
                                        string file = MapPath("~/ReportFiles/" + obj.FileName);
                                        obj.FileData = File.ReadAllBytes(obj.FileName);
                                        obj.IsOkay = provider.UpdateReport(obj.EntityId, obj.Name, obj.CategoryId, obj.FileName, obj.FileData);
                                        obj.FileName = Path.GetFileName(file);
                                        File.Delete(file);
                                    }
                                    else
                                        obj.IsOkay = provider.UpdateReport(obj.EntityId, obj.Name, obj.CategoryId);
                                    obj.Message = obj.IsOkay ? "İşlem başarılı." : "İşlem tamamlanamadı !";
                                }
                                break;
                            case ProcessModes.DeleteReportResult:
                                obj.IsOkay = provider.DeleteReport(obj.EntityId);
                                obj.Message = obj.IsOkay ? "İşlem başarılı." : "İşlem tamamlanamadı !";
                                break;
                            #endregion

                            #region Category results

                            case ProcessModes.AddCategoryResult:
                                obj.IsOkay = provider.AddCategory(obj.Name);
                                obj.Message = obj.IsOkay ? "İşlem başarılı." : "İşlem tamamlanamadı !";
                                break;
                            case ProcessModes.EditCategoryResult:
                                obj.IsOkay = provider.RenameCategory(obj.EntityId, obj.Name);
                                obj.Message = obj.IsOkay ? "İşlem başarılı." : "İşlem tamamlanamadı !";
                                break;
                            case ProcessModes.DeleteCategoryResult:
                                obj.IsOkay = provider.DeleteCategory(obj.EntityId);
                                obj.Message = obj.IsOkay ? "İşlem başarılı." : "İşlem tamamlanamadı !";
                                break;
                            #endregion

                            #region Refresh
                            case ProcessModes.Refresh:
                                obj.IsOkay = true;
                                break;
                            #endregion

                            #region default case
                            default:
                                obj.IsOkay = false;
                                obj.Message = "Beklenmeyen işlem tipi: " + obj.Mode.ToString();
                                break;
                            #endregion
                        }
                    }
                    catch (Exception ex)
                    {
                        obj.IsOkay = false;
                        obj.Message = ex.Message;
                        obj.Exception = ex.Source + Environment.NewLine + ex.StackTrace;
                    }
                }
            }
            obj.FileData = null;
            obj.FileChanged = false;
            e.Result = ser.Serialize(obj);
        }
    }
}